﻿#include"XZip.h"
//数据
//在压缩数据中写入压缩数据
void XZip::writeGZipData(const char* data, const size_t size)
{
	size_t currentSize = m_zipData.size();//当前字节大小
	/*if (currentSize == 0)
	{
		std::cout << "字典忘记写入了\n";
	}*/
	std::vector<char>* code = NULL;//哈夫曼编码数组
	char byteWrite = 0;//写入的一字节
	char charWriteIdx = 0;//字节内的比特位索引
	for (size_t i = 0; i < size; i++)
	{
		char ch = data[i];//遍历每一个字节
		code = tree.m_dictionaries[ch].code;
		//遍历编码
		for (auto& c : *code)
		{
			if (0 == c)
			{
				byteWrite &= ~(1 << (7 - charWriteIdx));
				++charWriteIdx;
			}
			else if (1 == c)
			{
				byteWrite |= (1 << (7 - charWriteIdx));
				++charWriteIdx;
			}
			if (charWriteIdx == 8)//写入了一字节
			{
				m_zipData.push_back(byteWrite);
				byteWrite = 0;
				charWriteIdx = 0;
			}
		}
	}
	if (charWriteIdx != 0)//剩下的比特位，写入
	{
		m_zipData.push_back(byteWrite);
	}
}
//在压缩文件中写入压缩数据
void XZip::writeGZipData(std::fstream& writeFile, std::fstream& readFile)
{
	//size_t size = read.tellg();//原文件大小
	//read.seekg(0,std::ios::beg);//移动文件指针到开头
 //   size_t currentSize = writeFile.tellg();//当前字节大小
	//if (currentSize == 0)
	//{
	//	std::cout << "字典忘记写入了\n";
	//}
	std::vector<char>* code = NULL;//哈夫曼编码数组
	char byteWrite = 0;//写入的一字节
	char charWriteIdx = 0;//字节内的比特位索引
	char ch = 0;//临时存储的字节
	while (!readFile.eof())
	{
		readFile.read(&ch, 1);
		code = tree.dictionaries()[ch].code;
		//遍历编码
		for (auto& c : *code)
		{
			if (0 == c)
			{
				byteWrite &= ~(1 << (7 - charWriteIdx));
				++charWriteIdx;
			}
			else if (1 == c)
			{
				byteWrite |= (1 << (7 - charWriteIdx));
				++charWriteIdx;
			}
			if (charWriteIdx == 8)//写入了一字节
			{
				writeFile.write(&byteWrite, 1);
				byteWrite = 0;
				charWriteIdx = 0;
			}
		}
	}
	if (charWriteIdx != 0)//剩下的比特位，写入
	{
		writeFile.write(&byteWrite, 1);
	}

}

//写入解压后的数据
static bool writeUnZip(std::vector<char>& unzipData, XHfmNode* node)
{
	//printf("%d ", XHfmTree_GetNodeData(node).ch);
	if (node->data().code != NULL)//当前的节点有数据
	{
		unzipData.push_back(node->data().ch);
		return true;
	}
	return false;
}
//获取解压后的数据
size_t XZip::readUnZipData(const char* data, const size_t size, size_t offset, size_t count, std::vector<char>& unZipData)
{
	if (count == 0)
		return offset;

	size_t curCount = 0;//当前字符出现次数


	XHfmNode* root = tree.XHfmTree();//根节点
	XHfmNode* currentNode = root;//当前节点
	size_t i = 0;
	for (; i < size - offset; i++)//遍历每一个字节
	{
		char byteRead = data[i + offset];//读取的一字节
		//字节内的比特位索引

		for (char charReadIdx = 0; charReadIdx < 8; charReadIdx++)//遍历每一个比特位
		{
			char temp = (byteRead >> (7 - charReadIdx)) & 0x01;
			if (temp == 0)//左边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->leftChild()))
				{
					currentNode = root;
					++curCount;
				}
			}
			else if (temp == 1)//右边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->rightChild()))
				{
					currentNode = root;
					++curCount;
				}
			}
			if (curCount == count)//已经遍历完了
				return offset + i + 1;
		}
	}
	return offset + i + 1;
}
//从文件读取获取解压后的数据
size_t XZip::readUnZipData(std::fstream& readFile, size_t count, std::vector<char>& unZipData)
{
	if (count == 0)
		return 0;

	size_t curCount = 0;//当前字符出现次数
	XHfmNode* root = tree.XHfmTree();//根节点
	XHfmNode* currentNode = root;//当前节点
	size_t i = 0;
	for (; i < count; i++)//遍历每一个字节
	{
		char byteRead =0;//读取的一字节
		//字节内的比特位索引
		//读取一个字节
		if (readFile.read((char*)&byteRead, sizeof(char)).gcount() != sizeof(char))
			return 0;
		for (char charReadIdx = 0; charReadIdx < 8; charReadIdx++)//遍历每一个比特位
		{
			char temp = (byteRead >> (7 - charReadIdx)) & 0x01;
			if (temp == 0)//左边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->leftChild()))
				{
					currentNode = root;
					++curCount;
				}
			}
			else if (temp == 1)//右边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->rightChild()))
				{
					currentNode = root;
					++curCount;
				}
			}
			if (curCount == count)//已经遍历完了
				return  i + 1;
		}
	}
	return i + 1;
}

//从文件读取获取解压后的数据
size_t XZip::readUnZipData(std::fstream& readFile, size_t count, std::fstream& writeFile)
{
	if (count == 0)
		return 0;

	size_t curCount = 0;//当前字符出现次数
	XHfmNode* root = tree.XHfmTree();//根节点
	XHfmNode* currentNode = root;//当前节点
	size_t i = 0;
	std::vector<char> unZipData;
	for (; i < count; i++)//遍历每一个字节
	{
		char byteRead = 0;//读取的一字节
		//字节内的比特位索引
		//读取一个字节
		if (readFile.read((char*)&byteRead, sizeof(char)).gcount() != sizeof(char))
			return 0;
		for (char charReadIdx = 0; charReadIdx < 8; charReadIdx++)//遍历每一个比特位
		{
			char temp = (byteRead >> (7 - charReadIdx)) & 0x01;
			if (temp == 0)//左边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->leftChild()))
				{
					currentNode = root;
					++curCount;
					writeFile.write((char*)& unZipData[0],1);
					unZipData.clear();
				}
			}
			else if (temp == 1)//右边
			{
				if (writeUnZip(unZipData, currentNode = currentNode->rightChild()))
				{
					currentNode = root;
					++curCount;
					writeFile.write((char*)&unZipData[0], 1);
					unZipData.clear();
				}
			}
			if (curCount == count)//已经遍历完了
				return  i + 1;
		}
	}
	return i + 1;
}